Primera Parte

Dr.Ā Oldemar RodrĆ­guez Rojas


Presentación de R y RStudio.

RStudio es un IDE por sus siglas en ingles Integrated Development Environment o Entorno De Desarrollo Integrado que facilita el interactuar con el lenguaje de programación R y los procesos de carga de datos, instalación y administración de paquetes, exportación de grÔficos y administración de archivos, entre otros.

Consola

La consola de RStudio nos permite interactuar con los comandos de R, es decir, ingresamos una instrucción en la consola y esta retornarÔ el resultado de le ejecución de ese comando, aunque ésta es una herramienta muy útil no es la mejor opción cuando nuestro código gana complejidad.

Editor de código

RStudio nos permite con su editor de código el escribir y ejecutar nuestro código con la facilidad de guardarlo para ejecutarlo cuando sea necesario.

Instalación de paquetes.

Consola

Podemos instalar paquetes en R utilizando la función install.packages, ésta recibe muchos parÔmetros pero solo dos de ellos son indispensables :

  • pkgs : nombre del paquete que se instalarĆ”.

  • dependencies : si su valor es TRUE se instalarĆ”n los paquetes de los que el paquete a instalar dependa.

install.packages("rattle", dependencies=TRUE)
install.packages("ggplot2", dependencies = TRUE)
install.packages("scales", dependencies = TRUE)
install.packages("MASS", dependencies=TRUE)
install.packages("tree", dependencies=TRUE)
install.packages("rpart", dependencies=TRUE)
install.packages("e1071", dependencies=TRUE)
install.packages("randomForest", dependencies=TRUE)
install.packages("kknn", dependencies=TRUE)
install.packages("class", dependencies=TRUE)
install.packages("RSDA", dependencies=TRUE)

RStudio

En la secciones se paquetes seleccionamos el botón install.

En la ventana Install Packages en la sección Packages escribe el nombre del paquete a instalar en este caso purrr y presionamos el botón Install.

Sintaxis BƔsica de R.

En su uso mƔs elemental podemos utilizar R como una simple calculadora, veamos algunos ejemplos para familiarizarnos con la consola de R.

# SUMA
2 + 2
[1] 4
3 + 4
[1] 7
# RESTA
5 - 1
[1] 4
# MULTIPLICACIƓN Y POTENCIA
-5 * 2
[1] -10
5 ^ 2
[1] 25

Ademas de operaciones podemos definir ā€œexpresionesā€ en las que en lugar de nĆŗmero definiremos variables, a diferencia de otros lenguajes para asignar a un valor a una variable utilizaremos el operator ā€œ<-ā€.

x <- 5
y <- 2
x + y
[1] 7

Vectores

El primer paso para trabajar con datos es tener claro el cómo y dónde estos serÔn almacenados, en R cualquier estructura que almacena datos se denomina objeto estos tiene características y comportamientos diferentes, el objeto mÔs simple en R es el vector por eso que R se conozca con un lenguaje de programación vectorizada ya que este esta optimizado para trabajar con esta estructura de datos, ademas esta estructura sirve de base para la construcción de estructuras mÔs complejas como veremos mÔs adelante.

Todos de los vectores si importar su tipo comparten una serie de caracterĆ­sticas que llamaremos propiedades las tres propiedades que comparten todos los vector son:

  • Type/Tipo : Indica el tipo de datos que se almacena (ā€œnumericā€,ā€œlogicalā€,ā€œintergerā€,ā€œcharacterā€,ā€œlistā€)
  • Length/Largo : Indica la cantidad de elementos que contiene un vector.
  • Attributes/Atributos : CaracterĆ­sticas adicionales propias del tipo de vector que se crea.

Existen dos tipos de vectores, los vectores atómicos y las listas, estos se diferencian en que los vectores atómicos sólo pueden contener un tipo de datos, es decir todos los elementos de un vector son del mismo tipo, mientras que las listas pueden contener elementos de diferentes clases.

Iniciaremos con el vector atómico de tipo numeric/numérico, este nos permite almacenar números positivos y negativos con o sin decimales así como valores propios de R como NA (not available/no disponible), NaN(Not a Number/No Un Número) e Inf (infinito).

# Creamos un vector de tipo numerico de largo 1 que almacena el valor 10
primer.vector <- 10
Lectura recomendada
Si desea conocer mÔs sobre la guía de estilo de R, es decir, como se recomienda escribir el código para su fÔcil lectura, puedes revisar la guía propuesta por google en el siguiente enlace https://google.github.io/styleguide/Rguide.xml

Asignación e indexación numérica.

El comando para crear un vector ā€œvaciĆ³ā€ es el comando vector, al que debemos indicarle los siguiente parĆ”metros :

  • mode : Tipo de datos que almacenarĆ” el vector.
  • length : Cantidad de valores que tendrĆ” el vector.
# Se crear un vector "vacio" de tipo numerico de largo 10.
vector.vacio <- vector(mode = "numeric", length = 10)
vector.vacio
 [1] 0 0 0 0 0 0 0 0 0 0

En este caso al inicializar un vector numerio todos los ā€œcasillasā€ tienen como valor inicial 0.

Otra forma muy utilizada de crear un vector es con la función ā€˜c’ que nos permite crear un vector a partir de la unión o combinación de otros vectores, en este caso el vector sera del tipo que permita representar a todos los valores que indiquemos y su largo sera igual a la cantidad de vectores que combinemos.

# Se crea un vector tipo numerico con los valores indicados.
vector.con.datos <- c(2, 3, 5, 2, 1)
vector.con.datos
[1] 2 3 5 2 1

Una vez un vector esta cargado con datos el siguiente paso es el cómo extraer los datos, la forma mĆ”s simple es utilizando la indexación numĆ©rica, es decir, indicar cual el nĆŗmero de ā€œcasillaā€ del valor a recuperar utilizando la función ā€˜[ ]’.

# casillas            1  2  3  4  5
vector.con.datos <- c(2, 3, 5, 2, 1)

Se recupera el valor almacenado en la casilla 1.

#                       1  2  3  4  5
# vector.con.datos <- c(2, 3, 5, 2, 1)
vector.con.datos[1]
[1] 2

Se recupera el valor almacenado en la casilla 3.

#                       1  2  3  4  5
# vector.con.datos <- c(2, 3, 5, 2, 1)
vector.con.datos[3]
[1] 5

No solamente podemos ingresar un valores sino que se pueden utilizar mĆŗltiples valores (almacenados en un vector), teniendo como resultado mĆŗltiples ā€œcasillasā€.

#                       1  2  3  4  5
# vector.con.datos <- c(2, 3, 5, 2, 1)
vector.con.datos[c(2,3,4)]
[1] 3 5 2
Otra forma de extraer mĆŗltiples ā€œcasillasā€ es creando un vector que contenga una secuencia de nĆŗmeros, esto podemos hacerlo gracias la función ā€˜:’.

Secuencia de nĆŗmeros desde 1 hasta 3

1:3
[1] 1 2 3

Secuencia de nĆŗmeros desde 9 hasta 2

9:2
[1] 9 8 7 6 5 4 3 2

Secuencia de nĆŗmeros desde -5 hasta 5

-5:5
 [1] -5 -4 -3 -2 -1  0  1  2  3  4  5

Secuencia de nĆŗmeros desde -1.25 hasta 3

-1.25:3
[1] -1.25 -0.25  0.75  1.75  2.75

Al pasar como parametro la una secuencia de números tendremos como resultado las casillas indicadas en el orden en el que se encuentran los paramentos, aunque se puedan crear secuencias con decimales la indexación solo admite números enteros positivos.

#                       1  2  3  4  5
# vector.con.datos <- c(2, 3, 5, 2, 1)
vector.con.datos[2:5]
[1] 3 5 2 1
#                       1  2  3  4  5
# vector.con.datos <- c(2, 3, 5, 2, 1)
vector.con.datos[5:2]
[1] 1 2 5 3

Aunque tambiĆ©n se puede indexar un vector utilizando valores negativos el comportamiento de esta acción sera opuesto al obtenido utilizando valores positivos, es decir, en lugar de seleccionar una ā€œcasillaā€ del vector estaremos omitiendo dicha casilla de los valores a seleccionar.

#                       1  2  3  4  5
# vector.con.datos <- c(2, 3, 5, 2, 1)
vector.con.datos[-1]
[1] 3 5 2 1
#                       1  2  3  4  5
# vector.con.datos <- c(2, 3, 5, 2, 1)
vector.con.datos[-c(2,3)]
[1] 2 2 1
Error ComĆŗn

No es posible extraer valores de un vector utilizando indice positivos y negativos vector.con.datos[c(1,-3,-4))]
esta operación no esta permitida y genera el siguiente error : only 0’s may be mixed with negative subscripts.

la función c nos permite unir vectores sin importar su largo.

vector.a <- c(1,3,5)
vector.b <- c(2,4,6)
nuevo.vector  <- c(vector.a, vector.b)
nuevo.vector
[1] 1 3 5 2 4 6

Operadores MatemƔticos Y Funciones Estadƭsticas.

Un primer posible abordaje a R como lenguaje de programación es su capacidad para realizar cÔlculos matemÔticos y estadísticos.

Algunas funciones matemticas en R
Metodo Descripcion Ejemplo
+ Suma entre dos vectores 2 + 3 = 6
- Resta entre dos vectores 2 - 3 = 1
* Multiplicaci<U+00F3>n entre dos vectores 2 * 2 = 4
/ Divis<U+00F3>n entre vectores 8 / 2 = 4
^ Potencias entre vectores 5 ^ 2 = 25
%% Modulo 3 %% 2 = 1
log10 Logaritmo en base 10 log10(10) = 1
log2 Logaritmo en base 2 log2(10) = 3.32
sqrt Raiz cuadrada sqrt(25) = 5
cos Coseno cos(10) = -0.83
sin Seno sin(10) = -0.54
tan Tangente tan(10) = 0.64
a Las funciones que tengan como entreda dos o m<U+00E1>s vectores retornaran un vector de la longitud del m<U+00E1>s largo.
b Las funciones que tiene como entreda s<U+00F3>lo un vector (ej. sqrt) aplicar<U+00E1> el c<U+00E1>lculo a cada uno de los valores del vector de forma independiente dando como resultado un vector con la misma longitud que el original.

Al realizar operaciones sobre vectores hay algunas reglas que se deben tener en cuenta, estas se verĆ”n poco a poco a lo largo del curso, una de ellas es la ā€œley de reciclajeā€ cuando se aplican operaciones sobre dos vectores estos deben tener el mismo largo o R automĆ”ticamente reciclarĆ” al mĆ”s pequeƱo de estos.

vector.corto <- c(1, 4, -3)
vector.largo <- c(1, 4, 8, 0, 1, -5, 3)

vector.corto + vector.largo
Warning in vector.corto + vector.largo: longitud de objeto mayor no es
m'ultiplo de la longitud de uno menor
[1]  2  8  5  1  5 -8  4

Como podemos ver en el mensaje de alerta que nos da R ambos vectores tienen largos distintos asĆ­ que el mĆ”s corto fue ā€œrecicladoā€,el mensaje tambiĆ©n nos indica que el largo del vector pequeƱo no es mĆŗltiplo del grande lo que quiere decir que para completar el largo necesario se repitió el vector parcialmente, el reciclaje consiste en que comenzando por el primero de sus valores estos serĆ”n repetidos hasta que ambos vectores tengan el mismo largo, dando como resultado una operación como la siguiente.

R tambiƩn nos ofrece facilidades para realizar cƔlculos estadƭsticos entre algunas de las funciones que ofrece estƔn.

(para los ejemplos de la siguiente tabla se utiliza como valor de la variable x el vector c(1,2,3,7,6,5,4))

Algunas funciones estadisticas en R
Metodo Descripcion Ejemplos
min Valor m<U+00ED>nimo min(x) = 1
max Valor m<U+00E1>ximo max(x) = 7
mean Media mean(x) = 4
median Mediana median(x) = 4
sd Desviaci<U+00F3>n estandar sd(x) = 2.16
var Varianza var(x) = 4.66
a Para mirar la lista completa de funciones estadisticas de R se puede ejecutar la instrucci<U+00F3>n ā€˜help(package = stats)’

Otras funciones Ćŗtiles son :

  • rnorm : Datos aleatorios con distribución normal
rnorm(50)
 [1] -1.009595788  0.394099888 -0.181284372  2.439392962 -0.893575196
 [6]  0.295464539 -0.773958702  0.167328982 -1.889053206  0.684244179
[11] -0.793817988 -0.100636307 -1.959650048  1.663944102  0.242318064
[16]  0.006766843  1.156514044  1.148667132 -0.288549031 -0.497686189
[21]  0.244362617 -0.370654226 -0.808654921  0.449276331  1.546289080
[26]  1.550028618 -1.080959883 -0.053562448 -1.089591034 -0.469030198
[31]  0.274018417 -1.594460179  0.314727427  1.914868759 -0.694313107
[36] -0.726500817  1.083617443 -0.277550836 -1.692075267 -1.901168568
[41]  0.828680298  0.103500424 -0.111948432  1.184401589  0.875109234
[46] -0.334421771 -0.994909915  0.415297763 -1.195267501  1.280788266
  • runif : Datos aleatorios con distribución uniforme
runif(50)
 [1] 0.309370265 0.631092930 0.724478194 0.265030753 0.861690758
 [6] 0.873986088 0.544992406 0.626925218 0.884330998 0.621474870
[11] 0.242303927 0.003212954 0.433846924 0.493207783 0.525286394
[16] 0.622354524 0.369687279 0.085991534 0.038404094 0.704838911
[21] 0.121887010 0.393949535 0.104944755 0.586438388 0.384806205
[26] 0.852128960 0.657789784 0.851261921 0.662850167 0.921516253
[31] 0.365890198 0.043709425 0.462831846 0.155412728 0.152024192
[36] 0.198194383 0.092178145 0.734778361 0.945484245 0.515278823
[41] 0.930462348 0.657216372 0.190339156 0.966489957 0.149808079
[46] 0.196110352 0.577600442 0.126943711 0.759795877 0.754494377
  • sample : Muestra aleatoria de los datos.
datos <- 1:50
# Se selecciona al azar 10 valores del vector 'datos'
sample(datos,10)
 [1] 30  3 11 32 15  1 29 25 48 43
  • summary : Resuman estadĆ­stico de los datos.
summary(datos)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00   13.25   25.50   25.50   37.75   50.00 

Al inicio de este documento se comentó que existe en R un objeto designado para representar los datos ausentes denominado NA, al operar funciones estadísticas sobre vectores que contengan valores NA hay que tomar en cuenta que toda operación matemÔtica que se aplique sobre datos de tipo NA tendrÔ como resultado NA por lo que, por ejemplo, al calcular la media de un vector si uno de sus valores es NA el resultado del cÔlculo sera NA como vemos a continuación.

vector.con.na <- c(2,3,4,5,NA,4,2,4)
mean(vector.con.na)
[1] NA

Para evitar este resultado gran parte de las funciones estadísticas en R tiene el parÔmetro na.rm éste cuando se le asigna el valor TRUE indica a la función que los valores NA deben ser ignorados al realizar la operación.

mean(vector.con.na, na.rm = TRUE)
[1] 3.428571

Vectores Lógicos

Una vez visto un poco el como trabajar con vectores de tipo numérico es momento de conocer los vectores de tipo lógico, este tipo de vectores sin importar su longitud sólo puede contener dos posibles valores TRUE/VERDADERO o FALSE/FALSO, estos también pueden resumirse como T o F (siempre en mayúsculas).

vector.logico <- c(TRUE,FALSE,FALSE,FALSE,T,F,FALSE)
vector.logico
[1]  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE

Este tipo de vector es utilizado normalmente utilizado para almacenar variables que sólo tengan dos posibles valores como ā€œfraudeā€ o ā€œno fraudeā€, asĆ­ como el resultado de operaciones relacionales o lógicas.

Operadores Relacionales y Lógicos.

Los operadores relacionales con los que se cuenta en R son :

Funciones relacionales en R
Metodo Descripcion Ejemplo
< Menor que 2 < 6 = TRUE
> Mayor que 2 > 6 = FALSE
<= Menor o igual 3 <= 3 = TRUE
>= Mayor o igual 2 >= 3 = FALSE
== Igual 2 == 2 = TRUE
!= Diferente 2 != 2 = FALSE

Las operaciones relacionales entre vectores tambiĆ©n siguen la ā€œley del reciclajeā€ vista en el caso de los vectores numĆ©ricos, por ejemplo :

vector.uno <- 2
vector.dos <- c(2,4,3)
vector.tres <- c(9,4,2,-1,4)
vector.uno >= vector.dos
[1]  TRUE FALSE FALSE
vector.dos <= vector.tres
Warning in vector.dos <= vector.tres: longitud de objeto mayor no es
m'ultiplo de la longitud de uno menor
[1]  TRUE  TRUE FALSE FALSE  TRUE
vector.tres == vector.uno
[1] FALSE FALSE  TRUE FALSE FALSE

los operadores relacionales nos son de utilidad para operar sobre vectores numéricos pero para operar con vectores lógicos existen dos operadores que permiten trabajar con este tipo de vectores.

Operador AND/Y

Este retornarÔ TRUE/VERDADERO sólo cuando todas sus entradas sean TRUE/VERDADERO como se puede ver en la siguiente tabla.

Tabla de valores del operador AND/Y
X Y X & Y
TRUE TRUE TRUE
TRUE FALSE FALSE
FALSE TRUE FALSE
FALSE FALSE FALSE
Operador OR/O

Este retornarĆ” TRUE/VERDADERO si alguna de sus entradas sean TRUE/VERDADERO como se puede ver en la siguiente tabla.

Tabla de valores del operador OR/O
X Y X | Y
TRUE TRUE TRUE
TRUE FALSE TRUE
FALSE TRUE TRUE
FALSE FALSE FALSE

Indexación lógica

Una aplicación de las operaciones relacionales y lógicas es la capacidad de poder utilizar valores lógicos (TRUE o FALSE) para seleccionar u omitir valores de un vector, de forma similar a la indexación numérica.

edad <- c(15,13,18,67,24,32,45,75,24,35,42)
mayores.de.edad <- edad >= 18
menores.de.edad <- edad < 18
edad[mayores.de.edad]
[1] 18 67 24 32 45 75 24 35 42
edad[menores.de.edad]
[1] 15 13

Cuando se utiliza este tipo de indexación se pasa como entrada un vector lógico en el que los valores que correspondan a TRUE serÔn seleccionados y los que correspondan a FALSE serÔn omitidos.

# menores.de.edad
#        TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
edad <- c(15,  13,   18,    67,   24,   32,   45,   75,   24,   35,   42)
edad[menores.de.edad]
[1] 15 13
mayor.18.menor.35 <- edad >= 18 & edad <= 35
#        FALSE FALSE  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE
edad <- c(15,  13,    18,    67,   24,   32,   45,   75,   24,   35,   42)
edad[mayor.18.menor.35]
[1] 18 24 32 24 35

Matrices

Una matriz es un caso especial de un vector con un atributo adicional de dimension/dimensión esto hace que a diferencia de los vectores las matrices se representen de forma rectangular compuestas por filas (imagen de la izquierda) y por columnas (imagen de la derecha).

Creación de Matrices

En R la función para crear matrices es matrix la cual recibe cuatro parÔmetros (dos de estos opcionales)

  • data : vector con los valores que contendrĆ” la matriz.
  • nrow : cantidad de filas de la matriz.
  • ncol : cantidad de columnas de la matriz.
  • byrow : si su valor es TRUE la lectura de los datos se realiza por filas sino se realiza por columnas.
# Se crea una matriz de 4 columnas y 4 filas 
primera.matriz <- matrix(data = c(1,8,13,12,14,11,2,7,4,5,16,9,15,10,3,6),
                         nrow = 4, ncol = 4, byrow = T)
primera.matriz
     [,1] [,2] [,3] [,4]
[1,]    1    8   13   12
[2,]   14   11    2    7
[3,]    4    5   16    9
[4,]   15   10    3    6

los parÔmetros ncol y byrow pueden considerarse opcionales, en caso del primero cuando se establece la cantidad de filas (nrow) de la matriz R automÔticamente calcula cual es la cantidad de columnas necesarias para mantener la matriz rectangular, por otra parte el comando byrow lo que indica es el orden en que se colocaran los valores del vector data en la matriz como se muestra a continuación.

matriz.por.filas <- matrix(data = c(1,2,3,4,5,6,7,8,9,10,11,12),
                           nrow = 4, byrow = T)
matriz.por.filas
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
[4,]   10   11   12
matriz.por.columnas <- matrix(data = c(1,2,3,4,5,6,7,8,9,10,11,12),
                              nrow = 4, byrow = F)
matriz.por.columnas
     [,1] [,2] [,3]
[1,]    1    5    9
[2,]    2    6   10
[3,]    3    7   11
[4,]    4    8   12
Dimensión de una Matriz

Se puede conocer las dimensiones de una matriz utilizando la función dim, esta retorna un vector con dos valores el primero el número de filas y el segundo el número de columnas de la matriz.

primera.matriz
     [,1] [,2] [,3] [,4]
[1,]    1    8   13   12
[2,]   14   11    2    7
[3,]    4    5   16    9
[4,]   15   10    3    6
dim(primera.matriz)
[1] 4 4

En la siguiente imagen se representa dos matrices y sus respectivas dimensiones.


Indexación Numérica, Lógica y por Omisión en matrices.

Como vimos anteriormente en vectores numéricos es posible seleccionar y omitir valores de un vector utilizando indexación, este proceso puede realizarse también en matrices aunque la lógica de como esto funciona varia un poco.

primera.matriz
     [,1] [,2] [,3] [,4]
[1,]    1    8   13   12
[2,]   14   11    2    7
[3,]    4    5   16    9
[4,]   15   10    3    6
Indexación por fila
# La primer columna de la primera fila
primera.matriz[1,1]
[1] 1
# Todas las columnas de la tercera fila
primera.matriz[3,]
[1]  4  5 16  9

Cuando se omite el numero de columna que se desea seleccionar R interpreta que se desea seleccionar toda la fila.

Indexación por columna
# Segunda fila de la primera columna
primera.matriz[2,1]
[1] 14
# Todas la filas de la tercera columna
primera.matriz[,3]
[1] 13  2 16  3

Cuando se omite el numero de columna que se desea seleccionar R interpreta que se desea seleccionar toda la columna.

Nombres en una matriz

Una opción que facilita la lectura de una matriz es el poder poner nombre a las columnas

colnames(primera.matriz) <- c("A","B","C","D")
primera.matriz
      A  B  C  D
[1,]  1  8 13 12
[2,] 14 11  2  7
[3,]  4  5 16  9
[4,] 15 10  3  6
# Valores de la columna 'A' mayores a 5
mayor.5 <- primera.matriz[,"A"] > 5
primera.matriz[mayor.5,]
      A  B C D
[1,] 14 11 2 7
[2,] 15 10 3 6

Aunque ya vimos muchos todos los operadores matemĆ”ticos para disponibles en R para la multiplicaciones de matrices existe un operador especial %*% esto debido a que el operador * retorna la multiplicación de matrices multiplicando ā€œcasillaā€ por ā€œcasillaā€.

matriz.a <- matrix(data = c(1,2,3,4,5,6,7,8,9), nrow = 3)
matriz.b <- matrix(data = c(9,8,7,6,5,4,3,2,1), nrow = 3)

matriz.a * matriz.b
     [,1] [,2] [,3]
[1,]    9   24   21
[2,]   16   25   16
[3,]   21   24    9
matriz.a %*% matriz.b
     [,1] [,2] [,3]
[1,]   90   54   18
[2,]  114   69   24
[3,]  138   84   30

Unión de matrices

Al igual que con los vectores es posible unir matrices, esto utilizando las funciones rbin y cbin que como su nombre indican permiten unir dos matrices ya sea por sus filas o columnas.

matriz.a <- matrix(data = c(1, 2, 3, 4, 5, 6), nrow = 2)
matriz.a
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
matriz.b <- matrix(data = c(9, 8, 7, 6, 5, 4), nrow = 2)
matriz.b
     [,1] [,2] [,3]
[1,]    9    7    5
[2,]    8    6    4
nueva.matriz.filas <- rbind(matriz.a, matriz.b)
nueva.matriz.filas
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
[3,]    9    7    5
[4,]    8    6    4
nueva.matriz.columnas <- cbind(matriz.a, matriz.b)
nueva.matriz.columnas
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    3    5    9    7    5
[2,]    2    4    6    8    6    4

Apply : Operaciones sobre columnas o filas

Cuando se aplican funciones estadísticas o de cualquier otro tipo sobre una matriz la función apply nos permite seleccionar si esta función debe aplicarse a las filas o las columnas de la matriz, este funciones recibe los siguiente parÔmetros.

  • X : Matriz de datos sobre la que se realizaran las operaciones.
  • MARGIN : 1 = filas, 2 = columnas
  • FUN : función que se desea aplicar.
matriz.ejemplo <- matrix(data = c(1,18,16,12,14,14,2,7,4,5,11,9,13,11,13,6), nrow = 4, byrow = T)
matriz.ejemplo
     [,1] [,2] [,3] [,4]
[1,]    1   18   16   12
[2,]   14   14    2    7
[3,]    4    5   11    9
[4,]   13   11   13    6
# Suma sobre las filas de la matriz
apply(X = matriz.ejemplo, MARGIN = 1, FUN = sum)
[1] 47 37 29 43
# Suma sobre las columnas de la matriz
apply(X = matriz.ejemplo, MARGIN = 2, FUN = sum)
[1] 32 48 42 34

Listas

A diferencia de los vectores las listas pueden almacenar valores de diferentes tipos, estas juegan un papel fundamental en R ya que son la base de estructuras como las hojas de datos y el pilar la programación orientada a objetos en R, entre otros.

Creación de listas

j <- list(nombre = "Juan", salario = "200000", socio = TRUE)
j
$nombre
[1] "Juan"

$salario
[1] "200000"

$socio
[1] TRUE

Al igual que con las hojas de datos podemos utilizar la función $ para acceder a las variables de una lista indicando su nombre.

j$salario
[1] "200000"
j$socio
[1] TRUE

Unión de listas

Cuando tenemos mĆŗltiples listas es posible combinarlas todas en una sola lista, para esto existen dos formas de hacerlo :

empleado.1 <- list(nombre = "Juan", salario = "200000", socio = TRUE)
empleado.2 <- list(nombre = "Carlos", salario = "100000", socio = FALSE)
empleado.3 <- list(nombre = "Maria", salario = "300000", socio = TRUE)

la primera es creando una lista que contenga a las demĆ”s listas por eso en ocasiones a las listas en R se les conoce como ā€œvectores recursivosā€.

lista.profunda <- list(juan = empleado.1, carlos = empleado.2, maria = empleado.3)
lista.profunda
$juan
$juan$nombre
[1] "Juan"

$juan$salario
[1] "200000"

$juan$socio
[1] TRUE


$carlos
$carlos$nombre
[1] "Carlos"

$carlos$salario
[1] "100000"

$carlos$socio
[1] FALSE


$maria
$maria$nombre
[1] "Maria"

$maria$salario
[1] "300000"

$maria$socio
[1] TRUE

la segunda es creando un vector de listas con la función c teniendo como resultado una lista donde todos los datos estÔn al mismo nivel.

lista.plana <- c(juan = empleado.1, carlos = empleado.2, maria = empleado.3)
lista.plana
$juan.nombre
[1] "Juan"

$juan.salario
[1] "200000"

$juan.socio
[1] TRUE

$carlos.nombre
[1] "Carlos"

$carlos.salario
[1] "100000"

$carlos.socio
[1] FALSE

$maria.nombre
[1] "Maria"

$maria.salario
[1] "300000"

$maria.socio
[1] TRUE

Indexación en una lista

La indexación en una lista funciona de una forma ligeramente distinta a lo visto anteriormente, esto se debe a que los datos en una lista pueden tener diferentes niveles de profundidad.

a <- list(a = 1:3, b = "a string", c = pi, d = list(-1, -5))
str(a)
List of 4
 $ a: int [1:3] 1 2 3
 $ b: chr "a string"
 $ c: num 3.14
 $ d:List of 2
  ..$ : num -1
  ..$ : num -5

Ejemplo de indexación en una lista recursiva


otra forma de acceder a los datos en una lista recursiva es el reducir la ā€œprofundidadā€ de esta, para eso podemos utilizar los comandos flatten (del paquete purrr).

x <- list(list(a = 1, b = 2), list(c = 3, d = 4))
str(x)
List of 2
 $ :List of 2
  ..$ a: num 1
  ..$ b: num 2
 $ :List of 2
  ..$ c: num 3
  ..$ d: num 4

podemos utilizar flatten para hacer plana una lista recursiva

y <- flatten(x)
str(y)
List of 4
 $ a: num 1
 $ b: num 2
 $ c: num 3
 $ d: num 4

o utilizar flatten_dbl para convertir una lista plana (de ser posible) en un vector numƩrico.

flatten_dbl(y)
[1] 1 2 3 4


en el paquete purrr tambien se encuentran disponibles las funciones flatten_lgl, flatten_int, flatten_char, flatten_df

Funciones sobre lista con Lapply

Al aplicar funciones sobre los valores de una lista podemos utilizar la serie se funciones lapply.

ejemplo.lista <- list(a = c(2,4,3,5,6), b = c(2,7,6,4,52), c = c(7,5,7,0,1))

esta función recibe dos parÔmetros

  • X = lista con los datos a procesar.

  • FUN = funciona a aplicar sobre los datos.

lapply(X = ejemplo.lista, FUN = mean)
$a
[1] 4

$b
[1] 14.2

$c
[1] 4

a continuación se ilustra el como opera la función lapply sobre una lista.


Hojas de Datos

Las hojas de datos constituyen la manera mÔs eficiente mediante la cual R puede analizar un conjunto de datos estadísticos. Habitualmente se configuran de tal manera que cada fila se refiere a un individuo o unidad estadística, mientras que cada columna hace referencia a una variable estadística, esa configuración hace que visualmente una hoja de datos parezca una matriz. Sin embargo, como objetos de R, son cosas distintas.

Repaso a los tipos de variables.

Cuando se trabaja con hojas de datos es importante tener en cuenta el tipo de variable que se va a almacenar ya que esto puede eventualmente afectar el resultado las operaciones que se realizan con los datos, en estadĆ­stica existen dos grandes grupos de variables las cuantitativas y cualitativas.

A continuación veremos como crear variables nominales y ordinales en R.

Nominales : como se mencionó anteriormente este tipo de variable representa caracterĆ­sticas del individuo que no pueden ser ordenadas, por ejemplo, no es posible decir que ā€œamarilloā€ es mayor o menor en una escala que ā€œverdeā€ o que ā€œmasculinoā€ es mayor o menor en una escala que ā€œfemeninoā€.

colores <- factor(x = c("azul","rojo","amarillo","negro","verde"))
colores
[1] azul     rojo     amarillo negro    verde   
Levels: amarillo azul negro rojo verde

Es posible en una muestra no se vean representados todos los posible valores de una variable pero si estos son conocidos se recomienda indicarlos, en parƔmetro levels nos permite listar todos los valores admitidos para una variable, cualquier valor fuera de este conjunto sera representado con NA.

estado.civil <- factor(x = c("soltero","casado","no contesta"),levels = c("casado","viudo","soltero","union libre"))
estado.civil
[1] soltero casado  <NA>   
Levels: casado viudo soltero union libre
Recordatorio
En caso de no indicar valores en el parĆ”metro ā€œlevelsā€ este se genera automĆ”ticamente con los valores de ā€œxā€ en orden alfabĆ©tico.

Ordinales: para este caso se agrega el parÔmetro ordered que indica que los valores estÔn ordenados (en el orden que se indique en la variable levels), esto nos permite que se establezca la relación de superioridad o inferioridad entre estos.

grado.academico <- factor(x = c("primaria","doctorado","secundaria"), 
                          levels = c("primaria","secundaria","preparatoria",
                                     "bachillerato","licenciatura","maestria","doctorado"), 
                          ordered = T)
grado.academico
[1] primaria   doctorado  secundaria
7 Levels: primaria < secundaria < preparatoria < ... < doctorado
grupo.ordenado <- factor(x = c("malo","malo","regular","bueno","muy bueno","excelente"),
                         levels = c("muy malo","malo","regular","bueno","muy bueno","excelente"),
                         ordered = T)
grupo.ordenado
[1] malo      malo      regular   bueno     muy bueno excelente
Levels: muy malo < malo < regular < bueno < muy bueno < excelente
grupo.no.ordenado <- factor(x = c("malo","malo","regular","bueno","muy bueno","excelente"))
grupo.no.ordenado
[1] malo      malo      regular   bueno     muy bueno excelente
Levels: bueno excelente malo muy bueno regular

Buscamos el valor mĆ­nimo y el mĆ”ximo para la variable ā€œgrupo.ordenadoā€ y realizamos una comparación entre dos de sus valores

min(grupo.ordenado)
[1] malo
Levels: muy malo < malo < regular < bueno < muy bueno < excelente
max(grupo.ordenado)
[1] excelente
Levels: muy malo < malo < regular < bueno < muy bueno < excelente
grupo.ordenado[1] > grupo.ordenado[2]
[1] FALSE

Como vemos al ejecutar las siguientes lineas de código, no es posible realizar estas operaciones sobre una variable de tipo factor si sus valores no estÔn ordenados.

min(grupo.no.ordenado)
Error in Summary.factor(structure(c(3L, 3L, 5L, 1L, 4L, 2L), .Label = c("bueno", : 'min' not meaningful for factors
max(grupo.no.ordenado)
Error in Summary.factor(structure(c(3L, 3L, 5L, 1L, 4L, 2L), .Label = c("bueno", : 'max' not meaningful for factors
grupo.no.ordenado[1] > grupo.no.ordenado[2]
Warning in Ops.factor(grupo.no.ordenado[1], grupo.no.ordenado[2]): '>' not
meaningful for factors
[1] NA

Ahora que tenemos claro el tipo de dato que debemos utilizar según el caso vamos a ver cómo se construye una hoja de datos con los datos de 3 personas, que incluye el color de sus ojos (factor), su peso (numeric) y su altura (numeric). Empezaríamos definiendo el color de los ojos.

Creación y lectura

La función que nos permite crear una hoja de datos en R se denomina data.frame

ojos <- factor(c("Azules","Marrones","Marrones"),
               levels = c("Azules","Marrones","Verdes","Negros"))

Supongamos que los pesos y las alturas son, respectivamente, 68, 75, 88 y 1.65, 1.79, 1.85. Entonces, definirĆ­amos la hoja de datos mediante:

datos <- data.frame(Color.ojos = ojos, Peso = c(68, 75, 88), Altura = c(1.65, 1.79, 1.85))
datos
  Color.ojos Peso Altura
1     Azules   68   1.65
2   Marrones   75   1.79
3   Marrones   88   1.85
str(datos)
'data.frame':   3 obs. of  3 variables:
 $ Color.ojos: Factor w/ 4 levels "Azules","Marrones",..: 1 2 2
 $ Peso      : num  68 75 88
 $ Altura    : num  1.65 1.79 1.85

Así, tendremos tres variables, llamadas Color.ojos, Peso y Altura. Podemos forzar a que una matriz se convierta en una hoja de datos mediante la función as.data.frame. Por ejemplo la siguiente instrucción convertirÔ matriz en una hoja de datos.

matriz <- matrix(data = c(1, 5, 9, 2, 6, 0, 3, 7, 0, 4, 8, -1), nrow = 4, byrow = T)
matriz
     [,1] [,2] [,3]
[1,]    1    5    9
[2,]    2    6    0
[3,]    3    7    0
[4,]    4    8   -1
nuevos.datos <- as.data.frame(matriz)
nuevos.datos
  V1 V2 V3
1  1  5  9
2  2  6  0
3  3  7  0
4  4  8 -1

Como podemos ver automÔticamente R asigna un nombre a las variables, estas pueden extraerse o modificarse con la función names.

names(nuevos.datos)
[1] "V1" "V2" "V3"
names(nuevos.datos) <- c("Variable 1","Variable 2","Variable 3")
nuevos.datos
  Variable 1 Variable 2 Variable 3
1          1          5          9
2          2          6          0
3          3          7          0
4          4          8         -1

Pasos Para Una Correcta Lectura.

Los archivos csv o ā€œarchivos separados por comaā€ por su simplicidad y reducido tamaƱo es la forma mĆ”s popular para almacenar y distribuir tablas de datos, para su lectura utilizamos la función read.csv

setwd("~/Google Drive/MDCurso/Datos")
datos.estudiantes <- read.table('EjemploEstudiantes.csv', header=TRUE, sep=';',dec=',',row.names=1)

datos.estudiantes
       Matematicas Ciencias Espanol Historia EdFisica
Lucia          7.0      6.5     9.2      8.6      8.0
Pedro          7.5      9.4     7.3      7.0      7.0
Ines           7.6      9.2     8.0      8.0      7.5
Luis           5.0      6.5     6.5      7.0      9.0
Andres         6.0      6.0     7.8      8.9      7.3
Ana            7.8      9.6     7.7      8.0      6.5
Carlos         6.3      6.4     8.2      9.0      7.2
Jose           7.9      9.7     7.5      8.0      6.0
Sonia          6.0      6.0     6.5      5.5      8.7
Maria          6.8      7.2     8.7      9.0      7.0

en R leer un archivo de este tipo es muy sencillo pero existen algunas pautas a seguir para procurar la correcta lectura de los datos.

  1. Identificar el separador de datos y el separador decimal

El separador de datos es el carĆ”cter que se utiliza para indicar la separación entre columnas (parĆ”metro ā€œsepā€) y el separador decimal es el que indica la separación entre la parte entera y la parte decimal de un numero (parĆ”metro ā€œdecā€), la forma mĆ”s sencilla de identificarlo es abrir nuestro archivo con un editor de texto.

en la imagen anterior podemos ver que el separador de columnas es ā€˜;’ y el separador decimal seria ā€˜,’.

  1. Identificar si la tabla tiene nombres de fila o nombres de columna

Dependiendo de los datos con los que trabajemos las observaciones pueden o no tener un identificador Ćŗnico como lo puede ser ā€œcodigo de productoā€ o ā€œcedula de identidadā€ en este caso debemos indicar en el parĆ”metro row.names el nĆŗmero de la columna que se debe tomar como identificador, es tambiĆ©n muy comĆŗn que se le de un nombre a las columnas o variables en caso de que esto sea asĆ­ para nuestra tabla se debe en el parĆ”metro header indicar TRUE si las columnas tiene nombre o FALSE si estas no lo tienen.

  1. Verificar la correcta lectura de los datos.

Una vez la tabla ha sido leída es importante verificar que las columnas tengan el tipo de dato deseado para esto podemos utilizar la función str que nos retornara la estructura y el tipo de dato de cada unas de las variables de nuestra tabla.

str(datos.estudiantes)
'data.frame':   10 obs. of  5 variables:
 $ Matematicas: num  7 7.5 7.6 5 6 7.8 6.3 7.9 6 6.8
 $ Ciencias   : num  6.5 9.4 9.2 6.5 6 9.6 6.4 9.7 6 7.2
 $ Espanol    : num  9.2 7.3 8 6.5 7.8 7.7 8.2 7.5 6.5 8.7
 $ Historia   : num  8.6 7 8 7 8.9 8 9 8 5.5 9
 $ EdFisica   : num  8 7 7.5 9 7.3 6.5 7.2 6 8.7 7

Como podemos ver en este caso todas las variables fueron leƭdas de forma correcta ya que se espera que estas sean variables numƩricas.

Observemos el siguiente escenario, se decide agregar la variable Region a nuestra tabla de datos, esta es un código que indica la región a la que pertenece el estudiante.

setwd("~/Google Drive/MDCurso/Datos")
datos.estudiantes.v2 <- read.csv("EjemploEstudiantesv2.csv", header = TRUE,
                              sep = ";", dec = ",", row.names = 1)
datos.estudiantes.v2
       Matematica Ciencias Espanol Historia EdFisica Region
Lucia         7.0      6.5     9.2      8.6      8.0      1
Pedro         7.5      9.4     7.3      7.0      7.0      4
Ines          7.6      9.2     8.0      8.0      7.5      3
Luis          5.0      6.5     6.5      7.0      9.0      5
Andres        6.0      6.0     7.8      8.9      7.3      3
Ana           7.8      9.6     7.7      8.0      6.5      2
Carlos        6.3      6.4     8.2      9.0      7.2      1
Jose          7.9      9.7     7.5      8.0      6.0      1
Sonia         6.0      6.0     6.5      5.5      8.7      3
Maria         6.8      7.2     8.7      9.0      7.0      5
str(datos.estudiantes.v2)
'data.frame':   10 obs. of  6 variables:
 $ Matematica: num  7 7.5 7.6 5 6 7.8 6.3 7.9 6 6.8
 $ Ciencias  : num  6.5 9.4 9.2 6.5 6 9.6 6.4 9.7 6 7.2
 $ Espanol   : num  9.2 7.3 8 6.5 7.8 7.7 8.2 7.5 6.5 8.7
 $ Historia  : num  8.6 7 8 7 8.9 8 9 8 5.5 9
 $ EdFisica  : num  8 7 7.5 9 7.3 6.5 7.2 6 8.7 7
 $ Region    : int  1 4 3 5 3 2 1 1 3 5

como podemos ver esta variable es leƭda como una variable de numƩrica de tipo integer (entero) lo que es una lectura incorrecta ya que esta serƭa una variable cualitativa y no cuantitativa, esto podemos solucionarlo utilizando el parƔmetro colClasses como vemos en las siguientes instrucciones.

setwd("~/Google Drive/MDCurso/Datos")
datos.estudiantes.v2 <- read.csv("EjemploEstudiantesv2.csv", header = TRUE,
                              sep = ";", dec = ",", row.names = 1, 
                              colClasses = c("Region" = "factor"))
datos.estudiantes.v2
       Matematica Ciencias Espanol Historia EdFisica Region
Lucia         7.0      6.5     9.2      8.6      8.0      1
Pedro         7.5      9.4     7.3      7.0      7.0      4
Ines          7.6      9.2     8.0      8.0      7.5      3
Luis          5.0      6.5     6.5      7.0      9.0      5
Andres        6.0      6.0     7.8      8.9      7.3      3
Ana           7.8      9.6     7.7      8.0      6.5      2
Carlos        6.3      6.4     8.2      9.0      7.2      1
Jose          7.9      9.7     7.5      8.0      6.0      1
Sonia         6.0      6.0     6.5      5.5      8.7      3
Maria         6.8      7.2     8.7      9.0      7.0      5
str(datos.estudiantes.v2)
'data.frame':   10 obs. of  6 variables:
 $ Matematica: num  7 7.5 7.6 5 6 7.8 6.3 7.9 6 6.8
 $ Ciencias  : num  6.5 9.4 9.2 6.5 6 9.6 6.4 9.7 6 7.2
 $ Espanol   : num  9.2 7.3 8 6.5 7.8 7.7 8.2 7.5 6.5 8.7
 $ Historia  : num  8.6 7 8 7 8.9 8 9 8 5.5 9
 $ EdFisica  : num  8 7 7.5 9 7.3 6.5 7.2 6 8.7 7
 $ Region    : Factor w/ 5 levels "1","2","3","4",..: 1 4 3 5 3 2 1 1 3 5

Indexación numerica, lógica y por omisión

Al igual que los vector y las matrices podemos hacer en una hoja de datos indexación numérica, lógica y por omisión como se ve en los siguientes ejemplos :

# Todas la columnas de la fila 1
datos.estudiantes[1,]
      Matematicas Ciencias Espanol Historia EdFisica
Lucia           7      6.5     9.2      8.6        8
# Todas las filas de la columna 2
datos.estudiantes[,2]
 [1] 6.5 9.4 9.2 6.5 6.0 9.6 6.4 9.7 6.0 7.2
# Los estudiantes con notas en ciencias superiores a 8
buenos.ciencias <- datos.estudiantes[,2] >= 8
datos.estudiantes[buenos.ciencias,]
      Matematicas Ciencias Espanol Historia EdFisica
Pedro         7.5      9.4     7.3        7      7.0
Ines          7.6      9.2     8.0        8      7.5
Ana           7.8      9.6     7.7        8      6.5
Jose          7.9      9.7     7.5        8      6.0

Operador ā€˜$’

Adicional a los métodos de indexación ya vistos las hojas de datos nos permiten acceder a los valores de las variables a través de la función $.

datos.estudiantes$Matematica
 [1] 7.0 7.5 7.6 5.0 6.0 7.8 6.3 7.9 6.0 6.8
datos.estudiantes$Ciencias
 [1] 6.5 9.4 9.2 6.5 6.0 9.6 6.4 9.7 6.0 7.2

Fuentes

Esta semana del curso esta basada en los siguientes libros, aunque no es obligatorio se recomiendo su lectura.